// 常见的异步:定时器,Ajax
// console.log('任务1')
// console.log('任务2')
// setTimeout(() => {
//     console.log('任务3')
// }, 1000)
// console.log('任务4')
// 执行顺序：1，2，4，3，会发现所有异步任务都会在同步任务执行后再执行

// 一,Promise异步
// p1 = new Promise((resolve, reject) => {
//     resolve('任务成功')
//     reject('任务失败')
// })
// p1.then(data => {
//     console.log(data)
// })
// .catch(err => {
//     console.log(err)
// })
// p2 = new Promise((resolve, reject) => {
//     reject('任务失败')
// })
// p2.then(data=>{
//     console.log(data)
// }, err => {
//     console.log(err)
//     // throw new Error('失败!') // 抛出新异常,失败!
// })
/**
 * 总结Promise:
 * 它是一个类,实例化时需要传入一个匿名函数作为参数,参数有两个指定的名称
 * resolve => 对应成功, reject => 对应失败
 * 在实例化Promise类时候(new Promise(resolove, reject)=>{})
 * 它会自动调用{}内部的函数体进行异步执行
 * 然后我们在函数体内通过resolve()或者reject()声明异步执行的结果,并对外传参()
 * 注意resolve和reject后,相当于是return出来一个带状态:成功或失败和参数(括号里的)Promise对象
 * 然后通过.then(data => {异步执行成功后}, err => {异步执行失败后})
 * 当然也可以.then(data => {成功后}).catch=>(err => {失败后...})
 */

// Async
// 首先我们需要一个函数,且它return回来的值,必须是一个Promise对象
// function asyncTask () {
//     return new Promise((resolve, reject) => {
//         // 假装执行了一系列代码,最后返回值为result,布尔类型
//         result = true
//         // 通过result真假调取resolve / reject
//         if (result) {
//             resolve('成功!')
//         }else{
//             reject('失败!')
//         }
//     })
// }
// // 然后我们在其他函数前面声明 aysnc,即我们这个函数里面要异步调用某个返回值为Promise的函数
// async function main() {
//     console.log('1')
//     console.log('2')
//     // 用 await调用
//     data = await asyncTask()
//     console.log('3')
// }
// main()

// 二,Proxy代理对象
// 先定义一个对象
let obj = {
    name: '刘德华',
    age: 19
}
// 再定义一个Proxy代理对象(被代理的对象, {相关函数})
let p1 = new Proxy(obj, { //现在p1就是代理obj的对象
    // 获取值
    get(target, property, receiver) {
        return obj[property]
    },
    // 当代理对象的值发生修改时:
    set(target, property, value, receiver) {
        obj[property] = value //被代理对象的值同步修改
        console.log(obj[property]) //并且打印
    }
    // 还有很多其他函数...,参考文档
})
// counter = setInterval(() => {
//     p1.name = '王宝强' //会发现不停打印王宝强
// }, 1000)

// 三,Module模块
// 一个模块可以理解为一个文件
// ESM(浏览器)
/**
 * 1,html script标签声明 type="module"
 * 2,暴露内容 export default { 该模块要暴露的属性,方法... },假设文件为a.js
 * 3,其他文件引用: import xxx from './a.js'
 * 4,如果我是 export 变量名/方法名 进行暴露?
 * 5,那么我需要"解构引用": import{同名变量名,同名方法名,同名as新别名} from './a.js'
 */
// CommenJS(NODEJS)
/**
 * 定义模块module.export={属性,方法}
 * 导入模块let moduleA = require('路径')
 */